﻿#include "funtestwidget.h"

QFunTestWidget::QFunTestWidget(int i32AxiNo,QWidget *parent) : QWidget(parent)
{
    _i32FrameCnt = 0;

    _i32ShowCnt = 0;

    _bStartSaveData = false;

    _bCaclData = false;

    _i32AxisSelect = i32AxiNo;

    st_workmodeParam l_param;
    l_param.sName = "累加运动模式";
    l_param.paramCnt = 1;
    l_param.param1.sParamName = "累加值";
    l_param.param1.lfCoeff = 1;
    l_param.param1.lfParamMin = -32768;
    l_param.param1.lfParamMax = 32767;
    l_param.param1.sUnit = "urad";
    l_param.param1.lfdefaultdata = 20;
    _workModeParamMap[0x7A] = l_param;

    l_param.sName = "正弦模式";
    l_param.paramCnt = 2;
    l_param.param1.sParamName = "扫描频率";
    l_param.param1.lfCoeff = 1000;
    l_param.param1.lfParamMin = 0.1;
    l_param.param1.lfParamMax = 5;
    l_param.param1.sUnit = "Hz";
    l_param.param1.lfdefaultdata = 2;

    l_param.param2.sParamName = "扫频幅度";
    l_param.param2.lfCoeff = 1;
    l_param.param2.lfParamMin = 0;
    l_param.param2.lfParamMax = 5;
    l_param.param2.sUnit = "urad";
    l_param.param2.lfdefaultdata = 500;

    _workModeParamMap[0x7B] = l_param;

    l_param.sName = "阶跃模式";
    l_param.paramCnt = 2;
    l_param.param1.sParamName = "扫描频率";
    l_param.param1.lfCoeff = 1000;
    l_param.param1.lfParamMin = 0.1;
    l_param.param1.lfParamMax = 5;
    l_param.param1.sUnit = "Hz";
    l_param.param1.lfdefaultdata = 2;

    l_param.param2.sParamName = "扫频幅度";
    l_param.param2.lfCoeff = 1;
    l_param.param2.lfParamMin = 0;
    l_param.param2.lfParamMax = 65535;
    l_param.param2.sUnit = "urad";
    l_param.param2.lfdefaultdata = 2000;

    _workModeParamMap[0x7C] = l_param;



    l_param.sName = "位置正弦扫频模式";
    l_param.paramCnt = 3;
    l_param.param1.sParamName = "扫描起始频率";
    l_param.param1.lfCoeff = 1;
    l_param.param1.lfParamMin = 1;
    l_param.param1.lfParamMax = 255;
    l_param.param1.sUnit = "Hz";
    l_param.param1.lfdefaultdata = 1;

    l_param.param2.sParamName = "扫描终止频率";
    l_param.param2.lfCoeff = 1;
    l_param.param2.lfParamMin = 1;
    l_param.param2.lfParamMax = 255;
    l_param.param2.sUnit = "Hz";
    l_param.param2.lfdefaultdata = 50;

    l_param.param3.sParamName = "扫频幅度";
    l_param.param3.lfCoeff = 10;
    l_param.param3.lfParamMin = 0;
    l_param.param3.lfParamMax = 1000;
    l_param.param3.sUnit = "urad";
    l_param.param3.lfdefaultdata = 500;

    _workModeParamMap[0x8C] = l_param;


    l_param.sName = "定位精度测试";
    l_param.paramCnt = 1;
    l_param.param1.sParamName = "给定角度";
    l_param.param1.lfCoeff = 16777216/360.0;
    l_param.param1.lfParamMin = 0;
    l_param.param1.lfParamMax = 360;
    l_param.param1.sUnit = "度";
    l_param.param1.lfdefaultdata = 5;

    _workModeParamMap[0xFF] = l_param;

    _i32CurrentWorkMode = 0x7A;

    InitUI();

    _pPlotDataTimer = new QTimer(this);
    connect(_pPlotDataTimer,&QTimer::timeout,this,[=](){plotRcvData();});

//    _pAxisBtnGroup->buttons()[0]->setChecked(true);
    _pWorkModeBtnGroup->buttons()[0]->setChecked(true);
    setParamInfo();

    void (QButtonGroup::*fn)(int) = &QButtonGroup::buttonClicked;
//    connect(_pAxisBtnGroup,fn,this,&QFunTestWidget::onAxisChange);

    connect(_pWorkModeBtnGroup,fn,this,&QFunTestWidget::onWorkModeChange);

    connect(_pStartTestBtn,&QPushButton::clicked,this,&QFunTestWidget::onStartTest);

    connect(_pSaveDataCheckBox,&QCheckBox::clicked,this,&QFunTestWidget::onSaveDataBtnClick);

    connect(_pCalcBtn,&QPushButton::clicked,this,[=]()
    {
        if(_bStartTest == true)
        {
            _pShowDataLabel->setText("");
            _bCaclData = true;
            _pCalcBtn->setEnabled(false);
        }
        else
        {
            QMessageBox::warning(this,"提示","请先开始测试");
        }
    });


}
/**
* @brief
* @note
*
*/
void QFunTestWidget::InitTableWidget()
{
    //参数设置
    _pParamShowTableWidget = new QTableWidget(this);
    QString sTableStyle = "QTableWidget{border:0px solid;font-size:20px;font-family: 'Microsoft YaHei';}";
    sTableStyle = sTableStyle + "QTableWidget::Item{border:0px solid;font-size:20px;font-family: 'Microsoft YaHei';}";
    _pParamShowTableWidget->setStyleSheet(sTableStyle);
    _pParamShowTableWidget->setShowGrid(false);
    _pParamShowTableWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); //垂直滚动条
    _pParamShowTableWidget->horizontalHeader()->setHidden(true);
    _pParamShowTableWidget->horizontalHeader()->setStretchLastSection(true);//最后一列充满
    _pParamShowTableWidget->verticalHeader()->hide();
    _pParamShowTableWidget->setColumnCount(4);
    _pParamShowTableWidget->setRowCount(4);

    _pParamShowTableWidget->setColumnWidth(0,180);
    _pParamShowTableWidget->setColumnWidth(2,180);

    _pParamShowTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);

    int nRow = 0;

    _pParamShowTableWidget->setItem(nRow,0,new QTableWidgetItem("当前位置:"));
    _pParamShowTableWidget->setItem(nRow,1,new QTableWidgetItem("0.0"));
    _pParamShowTableWidget->setItem(nRow,2,new QTableWidgetItem("当前速度:"));
    _pParamShowTableWidget->setItem(nRow,3,new QTableWidgetItem("0.0"));
    nRow++;

    _pParamShowTableWidget->setItem(nRow,0,new QTableWidgetItem("A相电流:"));
    _pParamShowTableWidget->setItem(nRow,1,new QTableWidgetItem("0.0"));
    _pParamShowTableWidget->setItem(nRow,2,new QTableWidgetItem("C相电流:"));
    _pParamShowTableWidget->setItem(nRow,3,new QTableWidgetItem("0.0"));
    nRow++;

    _pParamShowTableWidget->setItem(nRow,0,new QTableWidgetItem("电流过大状态:"));
    _pParamShowTableWidget->setItem(nRow,1,new QTableWidgetItem("未知"));
    _pParamShowTableWidget->setItem(nRow,2,new QTableWidgetItem("电流过流检测状态:"));
    _pParamShowTableWidget->setItem(nRow,3,new QTableWidgetItem("未知"));
    nRow++;
    _pParamShowTableWidget->setItem(nRow,0,new QTableWidgetItem("超速检测状态:"));
    _pParamShowTableWidget->setItem(nRow,1,new QTableWidgetItem("未知"));
}

/**
* @brief
* @note
*
*/
void QFunTestWidget::InitUI()
{
    InitTableWidget();


    _pSaveDataCheckBox = new QCheckBox("保存实时数据",this);

    _pWorkModeBtnGroup = new QButtonGroup(this);

    _pCurrentPlot = new QCustomPlot(this);
    setPlotStyle(_pCurrentPlot,"时间(ms)","角度(°)");

    QLabel* plabel1 = new QLabel("工作模式:",this);
    plabel1->setStyleSheet("QLabel{color:rgb(0,0,255);font-size:18px;font-family: 'Microsoft YaHei';}");

    QHBoxLayout* pHboxlayout1 = new QHBoxLayout();
    QHBoxLayout* pHboxlayout2 = new QHBoxLayout();
    for(int i = 0; i < _workModeParamMap.keys().size();i++)
    {
        int l_key = _workModeParamMap.keys().at(i);
        QString sName = _workModeParamMap.value(l_key).sName;
        QPushButton* pButton = new QPushButton(sName,this);
        pButton->setCheckable(true);
        setButtonStyleSheet(pButton);
        _pWorkModeBtnGroup->addButton(pButton,l_key);
        if(i/5==0)
        {
            pHboxlayout1->addWidget(pButton);
        }
        else
        {
            pHboxlayout2->addWidget(pButton);
        }

    }

    _pShowDataLabel = new QLabel(this);
    _pShowDataLabel->setMinimumHeight(100);
    _pShowDataLabel->setStyleSheet("color:rgb(0,0,255);font-size:20px;font-family: 'Microsoft YaHei';");



    QVBoxLayout*pVboxlayout = new QVBoxLayout();
    pVboxlayout->addWidget(_pSaveDataCheckBox,1);
    pVboxlayout->addWidget(plabel1,1);
    pVboxlayout->addLayout(pHboxlayout1,1);
    pVboxlayout->addLayout(pHboxlayout2,1);
    pVboxlayout->addWidget(createParamWidget(),4);


    QGridLayout* playout = new QGridLayout(this);
    playout->addItem(new QSpacerItem(10,50,QSizePolicy::Minimum,QSizePolicy::Minimum),0,0,1,1);
    playout->addLayout(pVboxlayout,1,0,1,1);
    playout->addWidget(_pShowDataLabel,2,0,1,1);
    playout->addWidget(_pParamShowTableWidget,3,0,1,2);

    playout->addWidget(_pCurrentPlot,0,1,3,1);

    playout->addItem(new QSpacerItem(10,300,QSizePolicy::Minimum,QSizePolicy::Maximum),4,0,1,1);


    playout->setColumnStretch(0,1);
    playout->setColumnStretch(1,2);

}

/**
* @brief
* @note
*
*/
QWidget* QFunTestWidget::createParamWidget()
{
    QWidget* pwidget = new QWidget(this);
    QVBoxLayout* pVBoxlayout = new QVBoxLayout(pwidget);

    for(int i = 0; i < 4;i++)
    {
        _pParamNameLabel[i] = new QLabel("累加值",this);
        _pParamNameLabel[i]->setStyleSheet("QLabel{color:rgb(0,0,0);font-size:18px;font-family: 'Microsoft YaHei';}");

        _pParamEdit[i] = new QLineEdit(this);
        QUIQss::setTxtQss(_pParamEdit[i], "#DCE4EC", "#1ABC9C");

        QHBoxLayout* pHboxlayout = new QHBoxLayout();
        pHboxlayout->setObjectName(QString::number(i)+"_hbox");

        pHboxlayout->addWidget(_pParamNameLabel[i],1);
        pHboxlayout->addWidget(_pParamEdit[i],2);

        pVBoxlayout->addLayout(pHboxlayout);
    }

    _pCalcBtn = new QPushButton("计算");
//    QUIQss::setBtnQss(_pStartTestBtn,"#1ABC9C", "#E6F8F5", "#2EE1C1", "#FFFFFF", "#16A086", "#A7EEE6");


    _pStartTestBtn = new QPushButton("开始测试");
//    QUIQss::setBtnQss(_pStartTestBtn,"#1ABC9C", "#E6F8F5", "#2EE1C1", "#FFFFFF", "#16A086", "#A7EEE6");
    QHBoxLayout* pHboxlayout1 = new QHBoxLayout();
    pHboxlayout1->addWidget(_pCalcBtn,1,Qt::AlignRight);
    pHboxlayout1->addWidget(_pStartTestBtn,1,Qt::AlignRight);
    pVBoxlayout->addLayout(pHboxlayout1);


    return pwidget;
}

///**
//* @brief
//* @note
//*
//*/
//QWidget* QFunTestWidget::createParamWidget()
//{
//    QWidget* pwidget = new QWidget(this);

//    _pParamNameLabel = new QLabel("累加值",this);
//    _pParamNameLabel->setStyleSheet("QLabel{color:rgb(255,255,255);font-size:18px;font-family: 'Microsoft YaHei';}");

//    _pParamEdit = new QLineEdit(this);
//    QUIQss::setTxtQss(_pParamEdit, "#DCE4EC", "#1ABC9C");

//    _pStartTestBtn = new QPushButton("开始测试");
//    _pStartTestBtnGroup->addButton(_pStartTestBtn,0x0);
//    QUIQss::setBtnQss(_pStartTestBtn,"#1ABC9C", "#E6F8F5", "#2EE1C1", "#FFFFFF", "#16A086", "#A7EEE6");

//    QGridLayout* playout = new QGridLayout(pwidget);
//    playout->addWidget(_pParamNameLabel,0,0,1,1);
//    playout->addWidget(_pParamEdit,0,1,1,2);
//    playout->addWidget(_pStartTestBtn,1,2,1,1);

//    return pwidget;
//}
///**
//* @brief
//* @note
//*
//*/
//QWidget* QFunTestWidget::createIdentifParamWidget()
//{
//    QWidget* pwidget = new QWidget(this);

//    _pScanFreqLabel = new QLabel("扫描频率",this);
//    _pScanFreqLabel->setStyleSheet("QLabel{color:rgb(255,255,255);font-size:18px;font-family: 'Microsoft YaHei';}");

//    _pScanFreqEdit = new QLineEdit(this);
//    QUIQss::setTxtQss(_pScanFreqEdit, "#DCE4EC", "#1ABC9C");

//    _pScanAmpLabel = new QLabel("扫描幅度",this);
//    _pScanAmpLabel->setStyleSheet("QLabel{color:rgb(255,255,255);font-size:18px;font-family: 'Microsoft YaHei';}");

//    _pScanAmpEdit = new QLineEdit(this);
//    QUIQss::setTxtQss(_pScanAmpEdit, "#DCE4EC", "#1ABC9C");

//    _pStartScanBtn = new QPushButton("开始扫频");
//    _pStartTestBtnGroup->addButton(_pStartScanBtn,0x01);
//    QUIQss::setBtnQss(_pStartScanBtn,"#1ABC9C", "#E6F8F5", "#2EE1C1", "#FFFFFF", "#16A086", "#A7EEE6");

//    QGridLayout* playout = new QGridLayout(pwidget);
//    playout->addWidget(_pScanFreqLabel,0,0,1,1);
//    playout->addWidget(_pScanFreqEdit,0,1,1,2);
//    playout->addWidget(_pScanAmpLabel,1,0,1,1);
//    playout->addWidget(_pScanAmpEdit,1,1,1,2);
//    playout->addWidget(_pStartScanBtn,2,2,1,1);

//    return pwidget;
//}
/**
* @brief
* @note
*
*/
void QFunTestWidget::setParamInfo()
{
    st_workmodeParam l_param = _workModeParamMap[_i32CurrentWorkMode];
    if(l_param.paramCnt == 1)//
    {
        setHBoxHide(QString::number(0)+"_hbox",false);
        setHBoxHide(QString::number(1)+"_hbox",true);
        setHBoxHide(QString::number(2)+"_hbox",true);
        setHBoxHide(QString::number(3)+"_hbox",true);
        QString sName = QString("%1(%2)").arg(l_param.param1.sParamName).arg(l_param.param1.sUnit);
        _pParamNameLabel[0]->setText(sName);
        _pParamEdit[0]->setToolTip(QString("%1%2-%3%2").arg(l_param.param1.lfParamMin).arg(l_param.param1.sUnit).arg(l_param.param1.lfParamMax));
        _pParamEdit[0]->setText(QString::number(l_param.param1.lfdefaultdata));

        _pStartTestBtn->setText("开始测试");

    }
    else if( l_param.paramCnt == 2)//两个变量
    {
        setHBoxHide(QString::number(0)+"_hbox",false);
        setHBoxHide(QString::number(1)+"_hbox",false);
        setHBoxHide(QString::number(2)+"_hbox",true);
        setHBoxHide(QString::number(3)+"_hbox",true);

        QString sName = QString("%1(%2)").arg(l_param.param1.sParamName).arg(l_param.param1.sUnit);
        _pParamNameLabel[0]->setText(sName);
        _pParamEdit[0]->setToolTip(QString("%1%2-%3%2").arg(l_param.param1.lfParamMin).arg(l_param.param1.sUnit).arg(l_param.param1.lfParamMax));
        _pParamEdit[0]->setText(QString::number(l_param.param1.lfdefaultdata));
        sName = QString("%1(%2)").arg(l_param.param2.sParamName).arg(l_param.param2.sUnit);
        _pParamNameLabel[1]->setText(sName);
        _pParamEdit[1]->setToolTip(QString("%1%2-%3%2").arg(l_param.param2.lfParamMin).arg(l_param.param2.sUnit).arg(l_param.param2.lfParamMax));
        _pParamEdit[1]->setText(QString::number(l_param.param2.lfdefaultdata));

        _pStartTestBtn->setText("开始扫描");
    }
    else if( l_param.paramCnt == 3)//3个变量
    {
        setHBoxHide(QString::number(0)+"_hbox",false);
        setHBoxHide(QString::number(1)+"_hbox",false);
        setHBoxHide(QString::number(2)+"_hbox",false);
        setHBoxHide(QString::number(3)+"_hbox",true);

        QString sName = QString("%1(%2)").arg(l_param.param1.sParamName).arg(l_param.param1.sUnit);
        _pParamNameLabel[0]->setText(sName);
        _pParamEdit[0]->setToolTip(QString("%1%2-%3%2").arg(l_param.param1.lfParamMin).arg(l_param.param1.sUnit).arg(l_param.param1.lfParamMax));
        _pParamEdit[0]->setText(QString::number(l_param.param1.lfdefaultdata));
        sName = QString("%1(%2)").arg(l_param.param2.sParamName).arg(l_param.param2.sUnit);
        _pParamNameLabel[1]->setText(sName);
        _pParamEdit[1]->setToolTip(QString("%1%2-%3%2").arg(l_param.param2.lfParamMin).arg(l_param.param2.sUnit).arg(l_param.param2.lfParamMax));
        _pParamEdit[1]->setText(QString::number(l_param.param2.lfdefaultdata));

        sName = QString("%1(%2)").arg(l_param.param3.sParamName).arg(l_param.param3.sUnit);
        _pParamNameLabel[2]->setText(sName);
        _pParamEdit[2]->setToolTip(QString("%1%2-%3%2").arg(l_param.param3.lfParamMin).arg(l_param.param3.sUnit).arg(l_param.param3.lfParamMax));
        _pParamEdit[2]->setText(QString::number(l_param.param3.lfdefaultdata));


        _pStartTestBtn->setText("开始扫描");
    }

}



/**
* @brief
*
**/
void QFunTestWidget::setPlotStyle(QCustomPlot* pPlot,QString xName,QString yName)
{
    pPlot->xAxis->setLabel(xName);
    pPlot->yAxis->setLabel(yName);

//    pPlot->xAxis->setRange(0, 1024);//设置范围
//    pPlot->yAxis->setRange(0, 100);

    pPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom /*| QCP::iSelectPlottables*/ | QCP::iMultiSelect);

    pPlot->addGraph();//增加通道
    pPlot->addGraph();//增加通道

    pPlot->graph(0)->setName("设定值");
    pPlot->graph(1)->setName("反馈值");


    QPen pen;
    pen.setColor(QColor(0,0,255));
    pen.setWidth(1);
    pPlot->graph(0)->setPen(pen);


    pen.setColor(QColor(255,0,0));
    pPlot->graph(1)->setPen(pen);


    pPlot->legend->setVisible(true);
    pPlot->legend->setFont(QFont("Helvetica",9));

}

/**
* @brief
* @note
*
*/
void QFunTestWidget::onWorkModeChange(int nIndex)
{
    _i32CurrentWorkMode = nIndex;
    setParamInfo();
}

/**
* @brief
* @note
*
*/
void QFunTestWidget::setHBoxHide(QString sObjectName,bool bHid)
{
    QHBoxLayout* pHboxlayout = this->findChild<QHBoxLayout*>(sObjectName);
    if(pHboxlayout == nullptr)
    {
        return;
    }

    for (int i = 0; i < pHboxlayout->count(); ++i)
    {
           QWidget* w = pHboxlayout->itemAt(i)->widget();
           if (w != nullptr)
           {
               w->setHidden(bHid);
            }
     }

}


void QFunTestWidget::setButtonStyleSheet(QPushButton* pBtn)
{

    pBtn->setStyleSheet(
                "QPushButton:checked { background-color: rgb(245,90,70);;color:white;}"
                "QPushButton:unchecked { background-color: rgb(200,200,200);;color:black;}"
                "QPushButton{background-color: rgb(200,200,200);padding:5px;border-radius:5px;color:black;"
                "font-size:18px;font-family: 'Microsoft YaHei';}"
                "QPushButton:disabled { background-color: rgb(200,200,200);color:black;}"

                                );

    pBtn->setMinimumHeight(40);
}

/**
* @brief
* @note
*
*/
void QFunTestWidget::sendParamData()
{
    st_workmodeParam l_param = _workModeParamMap[_i32CurrentWorkMode];

    float lfdata[4];
    for(int i = 0; i < 4; i++)
    {
        lfdata[i] = _pParamEdit[i]->text().toFloat();
    }

    //定位精度测试 新增
    if(_i32CurrentWorkMode == 0xff)
    {
        fourchar l_fourchar;
        l_fourchar.ui32data= lfdata[0]*l_param.param1.lfCoeff;
        emit signal_set_thresholdparam(_i32AxisSelect,0x2A,l_fourchar.i32data,0x03);
        _workModeParamMap[_i32CurrentWorkMode].param1.lfcurrentSetdata = lfdata[0];
        return;
    }

    if(l_param.paramCnt == 1)//单轴
    {
        fourchar l_fourchar;
        l_fourchar.ui32data= lfdata[0]*l_param.param1.lfCoeff;
        emit signal_startTest(_i32AxisSelect,_i32CurrentWorkMode,l_fourchar.ui32data,0);

        _workModeParamMap[_i32CurrentWorkMode].param1.lfcurrentSetdata = lfdata[0];

    }

    if(l_param.paramCnt == 2 )//单轴
    {
        fourchar l_fourchar;
        l_fourchar.u16data[1]= lfdata[0]*l_param.param1.lfCoeff;
        l_fourchar.u16data[0]= lfdata[1]*l_param.param2.lfCoeff;
        emit signal_startTest(_i32AxisSelect,_i32CurrentWorkMode,l_fourchar.ui32data,0);

        _workModeParamMap[_i32CurrentWorkMode].param1.lfcurrentSetdata = lfdata[0];
        _workModeParamMap[_i32CurrentWorkMode].param2.lfcurrentSetdata = lfdata[1];

    }

    if(l_param.paramCnt == 3 )//单轴
    {
        fourchar l_fourchar;

        l_fourchar.data[2] = lfdata[1]*l_param.param2.lfCoeff;//终止频率
        l_fourchar.data[3] = lfdata[0]*l_param.param1.lfCoeff;//起始频率
        l_fourchar.u16data[0] = lfdata[2]*l_param.param3.lfCoeff;

        emit signal_startTest(_i32AxisSelect,_i32CurrentWorkMode,l_fourchar.ui32data,0);

        _workModeParamMap[_i32CurrentWorkMode].param1.lfcurrentSetdata = lfdata[0];
        _workModeParamMap[_i32CurrentWorkMode].param2.lfcurrentSetdata = lfdata[1];

    }



}

/**
* @brief
* @note
*
*/
void QFunTestWidget::onStartTest()
{
    st_workmodeParam l_param = _workModeParamMap[_i32CurrentWorkMode];

    QString sText = _pStartTestBtn->text();
    if(sText.contains("开始") == true)//开始测试
    {
        _bCaclData = false;
        _pCalcBtn->setEnabled(true);

        _pPlotDataTimer->start(500);

        _pShowDataLabel->setText("");

        sendParamData();
        _xdatalist.clear();
        _ydatalist[0].clear();
        _ydatalist[1].clear();

        _ycacldatalist[0].clear();
        _ycacldatalist[1].clear();

        _pCurrentPlot->graph(0)->data().data()->clear();//清除数据
        _pCurrentPlot->graph(1)->data().data()->clear();//清除数据
        _i32FrameCnt = 0;

        _bStartTest = true;

        _pStartTestBtn->setText("停止测试");
        if(l_param.paramCnt == 2)
        {
            _pStartTestBtn->setText("停止扫描");
        }
    }
    else//停止测试
    {
        _pStartTestBtn->setText("开始测试");
        if(l_param.paramCnt == 2)
        {
            _pStartTestBtn->setText("开始扫描");
        }

        emit signal_startTest(_i32AxisSelect,0x8d,0,0);
        _bStartTest = false;
        _bCaclData = false;
        _pCalcBtn->setEnabled(true);
        _pPlotDataTimer->stop();
    }
}

/**
* @brief //数据处理
* @note
*
*/
void QFunTestWidget::caclData()
{
    if(_i32CurrentWorkMode == 0x7A)//累加运动
    {
        QString sInfo = "";

        float lfsum = 0.0;
        for(int i = 0; i < _ycacldatalist[0].size()-1;i++)
        {
            float lfdata = _ycacldatalist[1][i+1] - _ycacldatalist[1][i];
            lfsum = lfsum + pow(lfdata,2);
        }

        float lfAvg = qSqrt(lfsum/_ycacldatalist[1].size());

        lfAvg = lfAvg/180.0*M_PI*1e6;//urad

        float lfRel = lfAvg/_workModeParamMap[_i32CurrentWorkMode].param1.lfcurrentSetdata*100;//比例结果
        sInfo = "累加运动响应度为:"+QString::number(lfAvg)+"%\n";


        //计算平稳度
        float lfsum2 = 0.0;
        float lfsum_avg = 0.0;
        QVector<float> l_rel_data;
        for(int i = 0; i < _ycacldatalist[0].size();i++)
        {
            float lfdata = _ycacldatalist[0][i] - _ycacldatalist[1][i];
            lfsum_avg = lfsum_avg + lfdata;
            l_rel_data.append(lfdata);
        }

        lfsum_avg = lfsum_avg /_ycacldatalist[0].size();//平均值
        for(int i = 0; i < l_rel_data.size();i++)
        {
            float lfdata =l_rel_data[i] - lfsum_avg;
            lfsum2 = lfsum2 + lfdata*lfdata;
        }

        lfRel = qSqrt(lfsum2/(l_rel_data.size()-1));
        lfRel = lfRel/180.0*M_PI*1e6;
        lfRel = lfRel/_workModeParamMap[_i32CurrentWorkMode].param1.lfcurrentSetdata*100;
        sInfo = sInfo + "累加运动平稳度为:"+QString::number(lfRel)+"%\n";
        _pShowDataLabel->setText(sInfo);
    }

    if(_i32CurrentWorkMode == 0x7B)//正弦运动
    {
        //频率
        float lfFreq = _workModeParamMap[_i32CurrentWorkMode].param1.lfcurrentSetdata;


        int l_freqPoint_cnt = 1.0/lfFreq*500;
        int nFreqCnt = _ycacldatalist[0].size()/(float)l_freqPoint_cnt;//周期数

        if(nFreqCnt < 20)
        {
            _pShowDataLabel->setText("数据个数少于20个周期，无法完成计算");
            return;
        }

        float lfsum = 0.0;
        for(int i = l_freqPoint_cnt*2; i < _ycacldatalist[0].size();i++)
        {
            float lfdata = _ycacldatalist[0][i] - _ycacldatalist[1][i];

            lfsum = lfsum + pow(lfdata,2);
        }
        float lfAvg = qSqrt(lfsum/_ycacldatalist[0].size());

        lfAvg = lfAvg/180.0*M_PI*1e6;//urad
        _pShowDataLabel->setText("动态抖动为:"+QString::number(lfAvg)+"urad");
    }


    if(_i32CurrentWorkMode == 0x7C)//阶跃运动
    {
        //频率
        float lfFreq = _workModeParamMap[_i32CurrentWorkMode].param1.lfcurrentSetdata;

        int l_freqPoint_cnt = 1.0/lfFreq*500;
        int nFreqCnt = _ycacldatalist[0].size()/(float)l_freqPoint_cnt;//周期数

//        if(nFreqCnt < 6)
//        {
//            _pShowDataLabel->setText("数据个数少于6个周期，无法完成计算!");
//            return;
//        }
        //计算基准值
        double lfxmax = *std::max_element(std::begin( _ycacldatalist[0]), std::end(_ycacldatalist[0]));
        double lfxmin = *std::min_element(std::begin(_ycacldatalist[0]), std::end(_ycacldatalist[0]));

        float lfBasicdata = (lfxmax + lfxmin)/2.0;



        int nCnt = 0;
        float lfsum = 0.0;
        float lfmin[2] = {65535.0};
        for(int i = 0; i < nFreqCnt;i++)//空掉1个周期
        {
            for(int j = 0; j < l_freqPoint_cnt;j++)
            {
                int index = l_freqPoint_cnt*i+j;
                if(_ycacldatalist[0][index]-lfBasicdata > 0 && _ycacldatalist[1][index]-lfBasicdata > 0)
                {
                    float lfdelta = _ycacldatalist[0][index] - _ycacldatalist[1][index];
                    lfmin[0] = lfmin[0] > lfdelta?lfdelta:lfmin[0];
                }

                if(_ycacldatalist[0][index]-lfBasicdata < 0 && _ycacldatalist[1][index]-lfBasicdata < 0)
                {
                    float lfdelta = (_ycacldatalist[0][index] - _ycacldatalist[1][index]);
                    lfmin[1] = lfmin[1] < lfdelta?lfdelta:lfmin[1];
                }
            }

            lfsum = lfsum + qAbs(lfmin[0]) + qAbs(lfmin[1]);
            nCnt++;
            nCnt++;
        }


        lfsum = lfsum / nCnt;
        lfsum = lfsum/180.0*M_PI*1e6;//urad
        _pShowDataLabel->setText("超调幅度为:"+QString::number(qAbs(lfsum))+"urad");
    }

    if(_i32CurrentWorkMode == 0xff)//定位运动
    {
        //定位精度
        float lfsum2 = 0.0;
        float lfsum_avg = 0.0;
        QVector<float> l_rel_data;
        for(int i = 0; i < _ycacldatalist[0].size();i++)
        {
            float lfdata = _ycacldatalist[0][i] - _ycacldatalist[1][i];
            lfsum_avg = lfsum_avg + lfdata;
            l_rel_data.append(lfdata);
        }

        lfsum_avg = lfsum_avg /_ycacldatalist[0].size();//平均值
        for(int i = 0; i < l_rel_data.size();i++)
        {
            float lfdata =l_rel_data[i] - lfsum_avg;
            lfsum2 = lfsum2 + lfdata*lfdata;
        }

        float lfRel = qSqrt(lfsum2/(l_rel_data.size()));
        lfRel = lfRel/180.0*M_PI*1e6;
        QString sInfo = "定位精度:"+QString::number(lfRel)+"urad\n";
        _pShowDataLabel->setText(sInfo);
    }
}
/**
* @brief
*
**/
void QFunTestWidget::onSaveDataBtnClick()
{
    if(_pSaveDataCheckBox->checkState() == Qt::Checked)
    {
        QString sFileFullPath = QDateTime::currentDateTime().toString("yyyyMMddhhmmss")+".csv";
        sFileFullPath = QApplication::applicationDirPath()+"/data/"+sFileFullPath;

        m_savefile.setFileName(sFileFullPath);

        writeDataToFile("时间,方位A相电流(A),方位C相电流(A),俯仰A相电流(A),俯仰C相电流(A),方位指令值(°),方位反馈值(°),俯仰指令值(°),俯仰反馈值(°),方位速度指令(°/s),方位速度反馈(°/s),俯仰速度指令(°/s),俯仰速度反馈(°/s),方位Q相电流指令(A),方位Q相电流反馈(A),俯仰Q相电流指令(A),俯仰Q相电流反馈(A)\r");

        _i32SaveFrameCnt = 0;

        _bStartSaveData = true;

    }
    else
    {

        _bStartSaveData = false;

        writeDataToFile(m_sSaveDataInfo);
        m_sSaveDataInfo = "";
        m_savefile.close();
    }
}

void QFunTestWidget::writeDataToFile(QString str)
{
    if(m_savefile.fileName().isEmpty())
    {
        return;
    }

    if(!m_savefile.isOpen())
    {
        m_savefile.open(QFile::ReadWrite|QFile::Append);
    }

    m_savefile.write(str.toLocal8Bit());
}

/**
* @brief
*
**/
void QFunTestWidget::rcvFrameData(st_rcvdata rcvdata)
{
    _rcv_capdata = rcvdata;

    saveDataToFile();
    showStatus();


    //方位轴
    //位置 反馈值
    fourchar l_data;
    l_data.data[3] = 0;
    l_data.data[2] = _rcv_capdata.azimuthresponse_value[0];
    l_data.data[1] = _rcv_capdata.azimuthresponse_value[1];
    l_data.data[0] = _rcv_capdata.azimuthresponse_value[2];
    _lfAziResponsedata = l_data.ui32data*360.0/16777216;

    l_data.data[3] = 0;
    l_data.data[2] = _rcv_capdata.azimuthcmd_value[0];
    l_data.data[1] = _rcv_capdata.azimuthcmd_value[1];
    l_data.data[0] = _rcv_capdata.azimuthcmd_value[2];
    _lfAziSetdata = l_data.ui32data*360.0/16777216;

    //俯仰轴
    l_data.data[3] = 0;
    l_data.data[2] = _rcv_capdata.pitchresponse_value[0];
    l_data.data[1] = _rcv_capdata.pitchresponse_value[1];
    l_data.data[0] = _rcv_capdata.pitchresponse_value[2];
    _lfPitchResponsedata = l_data.ui32data*360.0/16777216;

    l_data.data[3] = 0;
    l_data.data[2] = _rcv_capdata.pitchcmd_value[0];
    l_data.data[1] = _rcv_capdata.pitchcmd_value[1];
    l_data.data[0] = _rcv_capdata.pitchcmd_value[2];
    _lfPitchSetdata = l_data.ui32data*360.0/16777216;



    //添加数据
    if(_bStartTest == false)
    {
        return;
    }

    _xdatalist.append(_i32FrameCnt*2);

    if(_i32AxisSelect == M_AXIS_AZI)
    {
        _ydatalist[0].append(_lfAziSetdata);
        _ydatalist[1].append(_lfAziResponsedata);
    }
    if(_i32AxisSelect == M_AXIS_PICTH)
    {
        _ydatalist[0].append(_lfPitchSetdata);
        _ydatalist[1].append(_lfPitchResponsedata);
    }

    if(_bCaclData == true)
    {
        if(_i32AxisSelect == M_AXIS_AZI)
        {
            _ycacldatalist[0].append(_lfAziSetdata);
            _ycacldatalist[1].append(_lfAziResponsedata);
        }
        if(_i32AxisSelect == M_AXIS_PICTH)
        {
            _ycacldatalist[0].append(_lfPitchSetdata);
            _ycacldatalist[1].append(_lfPitchResponsedata);
        }
        if(_ycacldatalist[0].size() >= 5000)
        {
            caclData();
            _bCaclData = false;
            _pCalcBtn->setEnabled(true);
            _ycacldatalist[0].clear();
            _ycacldatalist[1].clear();

        }

    }


    _i32FrameCnt++;

}

/**
* @brief
*
**/
void QFunTestWidget::saveDataToFile()
{

    twochar l_twodata;
    l_twodata.data[0] = _rcv_capdata.azimuthcurrent_A.data[1];
    l_twodata.data[1] = _rcv_capdata.azimuthcurrent_A.data[0];
    lfAziCurrentA = l_twodata.i16data*0.0001;

    l_twodata.data[0] = _rcv_capdata.azimuthcurrent_C.data[1];
    l_twodata.data[1] = _rcv_capdata.azimuthcurrent_C.data[0];
    lfAziCurrentC = l_twodata.i16data*0.0001;

    l_twodata.data[0] = _rcv_capdata.pitchcurrent_A.data[1];
    l_twodata.data[1] = _rcv_capdata.pitchcurrent_A.data[0];
    lfPitchCurrentA = l_twodata.i16data*0.0001;

    l_twodata.data[0] = _rcv_capdata.pitchcurrent_C.data[1];
    l_twodata.data[1] = _rcv_capdata.pitchcurrent_C.data[0];
    lfPitchCurrentC = l_twodata.i16data*0.0001;

    //方位轴
    //位置 反馈值
    fourchar l_data;
    l_data.data[3] = 0;
    l_data.data[2] = _rcv_capdata.azimuthresponse_value[0];
    l_data.data[1] = _rcv_capdata.azimuthresponse_value[1];
    l_data.data[0] = _rcv_capdata.azimuthresponse_value[2];
    lfAziPosResponse = l_data.ui32data*360.0/16777216;

    l_data.data[3] = 0;
    l_data.data[2] = _rcv_capdata.azimuthcmd_value[0];
    l_data.data[1] = _rcv_capdata.azimuthcmd_value[1];
    l_data.data[0] = _rcv_capdata.azimuthcmd_value[2];
    lfAziPosSet = l_data.ui32data*360.0/16777216;

    //俯仰轴
    l_data.data[3] = 0;
    l_data.data[2] = _rcv_capdata.pitchresponse_value[0];
    l_data.data[1] = _rcv_capdata.pitchresponse_value[1];
    l_data.data[0] = _rcv_capdata.pitchresponse_value[2];
    lfPitchPosResponse = l_data.ui32data*360.0/16777216;

    l_data.data[3] = 0;
    l_data.data[2] = _rcv_capdata.pitchcmd_value[0];
    l_data.data[1] = _rcv_capdata.pitchcmd_value[1];
    l_data.data[0] = _rcv_capdata.pitchcmd_value[2];
    lfPitchPosSet = l_data.ui32data*360.0/16777216;


    if(_rcv_capdata.loopcmd == 0x11)
    {
        //速度
        l_twodata.data[0] = _rcv_capdata.loopcmd_data.loopdata_11.azimuth_speed_response_value.data[1];
        l_twodata.data[1] = _rcv_capdata.loopcmd_data.loopdata_11.azimuth_speed_response_value.data[0];
        lfAziSpeedResponse = l_twodata.i16data /100.0;

        l_twodata.data[0] = _rcv_capdata.loopcmd_data.loopdata_11.azimuth_speed_cmd_value.data[1];
        l_twodata.data[1] = _rcv_capdata.loopcmd_data.loopdata_11.azimuth_speed_cmd_value.data[0];
        lfAziSpeedSet = l_twodata.i16data /100.0;



        //俯仰轴
        l_twodata.data[0] = _rcv_capdata.loopcmd_data.loopdata_11.pitch_speed_response_value.data[1];
        l_twodata.data[1] = _rcv_capdata.loopcmd_data.loopdata_11.pitch_speed_response_value.data[0];
        lfPitchSpeedResponse = l_twodata.i16data /100.0;

        l_twodata.data[0] = _rcv_capdata.loopcmd_data.loopdata_11.pitch_speed_cmd_value.data[1];
        l_twodata.data[1] = _rcv_capdata.loopcmd_data.loopdata_11.pitch_speed_cmd_value.data[0];
        lfPitchSpeedSet = l_twodata.i16data /100.0;


        //Q相电流 反馈值
        l_twodata.data[0] =  _rcv_capdata.loopcmd_data.loopdata_11.azimuth_currentQ_response_value.data[1];
        l_twodata.data[1] =  _rcv_capdata.loopcmd_data.loopdata_11.azimuth_currentQ_response_value.data[0];
        lfAziQResponsedata = l_twodata.i16data /10000.0;

        l_twodata.data[0] =  _rcv_capdata.loopcmd_data.loopdata_11.azimuth_currentQ_cmd_value.data[1];
        l_twodata.data[1] =  _rcv_capdata.loopcmd_data.loopdata_11.azimuth_currentQ_cmd_value.data[0];
        lfAziQSetdata = l_twodata.i16data /10000.0;

        //Q相电流
        l_twodata.data[0] =  _rcv_capdata.loopcmd_data.loopdata_11.pitch_currentQ_response_value.data[1];
        l_twodata.data[1] =  _rcv_capdata.loopcmd_data.loopdata_11.pitch_currentQ_response_value.data[0];
        lfPitchQResponsedata = l_twodata.i16data /10000.0;

        l_twodata.data[0] =  _rcv_capdata.loopcmd_data.loopdata_11.pitch_currentQ_cmd_value.data[1];
        l_twodata.data[1] =  _rcv_capdata.loopcmd_data.loopdata_11.pitch_currentQ_cmd_value.data[0];
        lfPitchQSetdata = l_twodata.i16data /10000.0;

    }

    if(_bStartSaveData == false)
    {
        return;
    }

    _i32SaveFrameCnt++;

    int l_time = _i32SaveFrameCnt*2;


    QString sInfo;
    sInfo = QString("%1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12,%13,%14,%15,%16,%17\r").arg(l_time).arg(lfAziCurrentA).arg(lfAziCurrentC)\
            .arg(lfPitchCurrentA).arg(lfPitchCurrentC).arg(lfAziPosSet,0,'f',6).arg(lfAziPosResponse,0,'f',6)\
            .arg(lfPitchPosSet,0,'f',6).arg(lfPitchPosResponse,0,'f',6).arg(lfAziSpeedSet).arg(lfAziSpeedResponse)\
            .arg(lfPitchSpeedSet).arg(lfPitchSpeedResponse).arg(lfAziQSetdata).arg(lfAziQResponsedata)\
            .arg(lfPitchQSetdata).arg(lfPitchQResponsedata);

    m_sSaveDataInfo = m_sSaveDataInfo + sInfo;
    if(m_sSaveDataInfo.size() > 1000)
    {
        writeDataToFile(m_sSaveDataInfo);
        m_sSaveDataInfo = "";
    }


}


/**
* @brief
*
**/
void QFunTestWidget::plotRcvData()
{
    if(_bStartTest == false)
    {
        return;
    }
    _pCurrentPlot->graph(0)->setData(_xdatalist,_ydatalist[0]);
    _pCurrentPlot->graph(1)->setData(_xdatalist,_ydatalist[1]);

    double lfxmax = *std::max_element(std::begin(_xdatalist), std::end(_xdatalist));
    double lfxmin = *std::min_element(std::begin(_xdatalist), std::end(_xdatalist));

    double lfymax0 = *std::max_element(std::begin(_ydatalist[1]), std::end(_ydatalist[1]));
    double lfymin0 = *std::min_element(std::begin(_ydatalist[1]), std::end(_ydatalist[1]));


    if((lfxmax) > 1000)
    {
        lfxmin = lfxmax - 1000;
    }

    if(lfxmax < 1000)
    {
        lfxmax = 1000;
    }
    _pCurrentPlot->xAxis->setRange((lfxmin),(lfxmax));//幅度数据
    _pCurrentPlot->yAxis->setRange(lfymin0,lfymax0);//幅度数据

    _pCurrentPlot->replot();
}

void QFunTestWidget:: showStatus()
{
    _i32ShowCnt ++;
    if(_i32ShowCnt% 50 != 0)
    {
        return;
    }
    int nRow = 0;

    if(_i32AxisSelect == 0x00)
    {
        _pParamShowTableWidget->item(nRow,1)->setText(QString::number(lfAziPosResponse));
        _pParamShowTableWidget->item(nRow,3)->setText(QString::number(lfAziSpeedResponse));
        nRow++;
        _pParamShowTableWidget->item(nRow,1)->setText(QString::number(lfAziCurrentA));
        _pParamShowTableWidget->item(nRow,3)->setText(QString::number(lfAziCurrentC));
        nRow++;
        _pParamShowTableWidget->item(nRow,1)->setTextColor(QColor(0,0,0));
        _pParamShowTableWidget->item(nRow,3)->setTextColor(QColor(0,0,0));

        QString sInfo = (_rcv_capdata.azimuthInfo&0x10)==0x10?"异常":"正常";
        _pParamShowTableWidget->item(nRow,1)->setText(sInfo);
        if(sInfo == "异常")
        {
            _pParamShowTableWidget->item(nRow,1)->setTextColor(QColor(255,0,0));
        }

        sInfo = (_rcv_capdata.azimuthInfo&0x20)==0x20?"异常":"正常";
        _pParamShowTableWidget->item(nRow,3)->setText(sInfo);
        if(sInfo == "异常")
        {
            _pParamShowTableWidget->item(nRow,3)->setTextColor(QColor(255,0,0));
        }
        nRow++;
        _pParamShowTableWidget->item(nRow,1)->setTextColor(QColor(0,0,0));
        sInfo = (_rcv_capdata.azimuthInfo&0x40)==0x40?"异常":"正常";
        _pParamShowTableWidget->item(nRow,1)->setText(sInfo);
        if(sInfo == "异常")
        {
            _pParamShowTableWidget->item(nRow,1)->setTextColor(QColor(255,0,0));
        }
    }

    if(_i32AxisSelect == 0x01)
    {
        _pParamShowTableWidget->item(nRow,1)->setText(QString::number(lfPitchPosResponse));
        _pParamShowTableWidget->item(nRow,3)->setText(QString::number(lfPitchSpeedResponse));
        nRow++;
        _pParamShowTableWidget->item(nRow,1)->setText(QString::number(lfPitchCurrentA));
        _pParamShowTableWidget->item(nRow,3)->setText(QString::number(lfPitchCurrentC));
        nRow++;
        _pParamShowTableWidget->item(nRow,1)->setTextColor(QColor(0,0,0));
        _pParamShowTableWidget->item(nRow,3)->setTextColor(QColor(0,0,0));

        QString sInfo = (_rcv_capdata.pitchInfo&0x10)==0x10?"异常":"正常";
        _pParamShowTableWidget->item(nRow,1)->setText(sInfo);
        if(sInfo == "异常")
        {
            _pParamShowTableWidget->item(nRow,1)->setTextColor(QColor(255,0,0));
        }

        sInfo = (_rcv_capdata.pitchInfo&0x20)==0x20?"异常":"正常";
        _pParamShowTableWidget->item(nRow,3)->setText(sInfo);
        if(sInfo == "异常")
        {
            _pParamShowTableWidget->item(nRow,3)->setTextColor(QColor(255,0,0));
        }
        nRow++;
        _pParamShowTableWidget->item(nRow,1)->setTextColor(QColor(0,0,0));
        sInfo = (_rcv_capdata.pitchInfo&0x40)==0x40?"异常":"正常";
        _pParamShowTableWidget->item(nRow,1)->setText(sInfo);
        if(sInfo == "异常")
        {
            _pParamShowTableWidget->item(nRow,1)->setTextColor(QColor(255,0,0));
        }
    }



}
